﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevExpress.XtraEditors;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.Data;
using System.ComponentModel;

namespace MM.Common.UI.Controls
{
    public class UCCheckedListBoxControl : PanelControl
    {
        // Fields
        private EventHandler checkClickEvent;
        private ItemCollection checkList;
        private ListModel checkListModel;
        private SelectedModel checkSelectedModel;
        private object dataSource;
        private FlowLayoutPanel FlowLayout = new FlowLayoutPanel();
        private XtraScrollableControl Scrollable = new XtraScrollableControl();

        // Methods
        public UCCheckedListBoxControl()
        {
            this.checkList = new ItemCollection(this);
            this.ItemSize = new Size(0x4f, 14);
            this.checkClickEvent = new EventHandler(this.CheckEdit_Click);
            base.SizeChanged += new EventHandler(this.UCCheckedListBoxControl_SizeChanged);
            base.SuspendLayout();
            this.FlowLayout.Dock = DockStyle.Top;
            this.FlowLayout.AutoSize = true;
            this.FlowLayout.AutoScroll = false;
            this.FlowLayout.FlowDirection = FlowDirection.LeftToRight;
            this.Scrollable.Controls.Add(this.FlowLayout);
            this.Scrollable.Location = new Point(0, 0);
            this.Scrollable.BackColor = Color.White;
            this.Scrollable.Size = base.Size;
            base.Controls.Add(this.Scrollable);
            base.ResumeLayout();
        }

        private void BindingDataTable()
        {
            this.Items.Clear();
            IEnumerator enumerator = (this.dataSource as DataTable).Rows.GetEnumerator();
            while (enumerator.MoveNext())
            {
                DataRow current = enumerator.Current as DataRow;
                if (!string.IsNullOrEmpty(this.DisplayMember) && !string.IsNullOrEmpty(this.ValueMember))
                {
                    this.Items.Add(current[this.DisplayMember].ToString(), current[this.ValueMember]);
                }
                else
                {
                    if (!string.IsNullOrEmpty(this.DisplayMember))
                    {
                        this.Items.Add(current[this.DisplayMember].ToString());
                        continue;
                    }
                    if (!string.IsNullOrEmpty(this.ValueMember))
                    {
                        this.Items.Add(current[this.ValueMember]);
                        continue;
                    }
                    this.Items.Add(current.ToString());
                }
            }
        }

        private void ChangeLayout()
        {
            this.FlowLayout.Dock = DockStyle.Left;
            this.FlowLayout.FlowDirection = FlowDirection.TopDown;
        }

        private void ChangeSelectedModel()
        {
            Action<CheckEdit> action = null;
            Action<CheckEdit> action2 = null;
            switch (this.checkSelectedModel)
            {
                case SelectedModel.Multiple:
                    if (action2 == null)
                    {
                        action2 = delegate(CheckEdit n)
                        {
                            n.Click += this.checkClickEvent;
                        };
                    }
                    this.FlowLayout.Controls.Cast<CheckEdit>().ToList<CheckEdit>().ForEach(action2);
                    return;

                case SelectedModel.Radio:
                    if (action == null)
                    {
                        action = delegate(CheckEdit n)
                        {
                            n.Click -= this.checkClickEvent;
                        };
                    }
                    this.FlowLayout.Controls.Cast<CheckEdit>().ToList<CheckEdit>().ForEach(action);
                    return;
            }
        }

        private void CheckEdit_Click(object sender, EventArgs e)
        {
            this.FlowLayout.Controls.Cast<CheckEdit>().ToList<CheckEdit>().ForEach(delegate(CheckEdit n)
            {
                n.Checked = false;
            });
        }

        private void DataBinding()
        {
            if (this.dataSource is DataTable)
            {
                this.BindingDataTable();
            }
        }

        private void UCCheckedListBoxControl_SizeChanged(object sender, EventArgs e)
        {
            this.Scrollable.Size = base.Size;
        }

        // Properties
        public ListModel CheckListModel
        {
            get
            {
                return this.checkListModel;
            }
            set
            {
                if (this.checkListModel != value)
                {
                    this.checkListModel = value;
                    this.ChangeLayout();
                }
            }
        }

        public SelectedModel CheckSelectedModel
        {
            get
            {
                return this.checkSelectedModel;
            }
            set
            {
                if (this.checkSelectedModel != value)
                {
                    this.checkSelectedModel = value;
                    this.ChangeSelectedModel();
                }
            }
        }

        public object DataSource
        {
            get
            {
                return this.dataSource;
            }
            set
            {
                if (this.dataSource != value)
                {
                    this.dataSource = value;
                    this.DataBinding();
                }
            }
        }

        public string DisplayMember { get; set; }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Localizable(true)]
        public ItemCollection Items
        {
            get
            {
                return this.checkList;
            }
        }

        public Size ItemSize { get; set; }

        public CheckEdit SelectedItem
        {
            get
            {
                return (from n in this.FlowLayout.Controls.Cast<CheckEdit>()
                        where n.Checked
                        select n).DefaultIfEmpty<CheckEdit>().First<CheckEdit>();
            }
        }

        public CheckEdit[] SelectedItems
        {
            get
            {
                return (from n in this.FlowLayout.Controls.Cast<CheckEdit>()
                        where n.Checked
                        select n).ToArray<CheckEdit>();
            }
        }

        public string SelectedText
        {
            get
            {
                return (from n in this.FlowLayout.Controls.Cast<CheckEdit>()
                        where n.Checked
                        select n.Text).DefaultIfEmpty<string>().First<string>();
            }
        }

        public string[] SelectedTexts
        {
            get
            {
                return (from n in this.FlowLayout.Controls.Cast<CheckEdit>()
                        where n.Checked
                        select n.Text).ToArray<string>();
            }
        }

        public object SelectedValue
        {
            get
            {
                return (from n in this.FlowLayout.Controls.Cast<CheckEdit>()
                        where n.Checked
                        select n.Tag).DefaultIfEmpty<object>().First<object>();
            }
        }

        public object[] SelectedValues
        {
            get
            {
                return (from n in this.FlowLayout.Controls.Cast<CheckEdit>()
                        where n.Checked
                        select n.Tag).ToArray<object>();
            }
        }

        public string ValueMember { get; set; }

        // Nested Types
        public class ItemCollection : CollectionBase
        {
            // Fields
            private UCCheckedListBoxControl listControl;

            // Methods
            public ItemCollection(UCCheckedListBoxControl ListControl)
            {
                this.listControl = ListControl;
            }

            public void Add(CheckEdit check)
            {
                base.List.Add(check);
                if (this.listControl.CheckSelectedModel == UCCheckedListBoxControl.SelectedModel.Radio)
                {
                    check.Click += this.listControl.checkClickEvent;
                }
                this.listControl.FlowLayout.Controls.Add(check);
            }

            internal void Add(object value)
            {
                this.Add(value.ToString(), value);
            }

            internal void Add(string Text)
            {
                this.Add(Text, null);
            }

            internal void Add(string Text, object value)
            {
                this.Add(Text, value, false);
            }

            private void Add(string Text, object value, bool isChecked)
            {
                this.Add(new CheckEdit { Text = Text, Tag = value, Checked = isChecked });
            }

            protected override void OnClear()
            {
                this.listControl.FlowLayout.Controls.Clear();
                base.OnClear();
            }

            public void Remove(CheckEdit check)
            {
                base.List.Remove(check);
            }

            // Properties
            public CheckEdit this[int index]
            {
                get
                {
                    return (this.listControl.Controls[index] as CheckEdit);
                }
                set
                {
                    base.List[index] = value;
                }
            }
        }

        public enum ListModel
        {
            Horizontal=0,
            Vertical=1
        }

        public enum SelectedModel
        {
            Multiple=0,
            Radio=1
        }
    }
}
